﻿using DeForm;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Media.Animation;
using Windows.UI.Xaml.Media.Imaging;
using Windows.UI.Xaml.Navigation;

// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238

namespace D_Form_App
{
    /// <summary>
    /// An empty page that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainPage : Page
    {
        ImageManipulator imageManipulator;

        public MainPage()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
        }

        void SynchronizeEffects()
        {
            imageManipulator.ClearEffectDescriptions();

            if (blurButton.IsChecked == true)
                imageManipulator.AddEffectDescription(new GaussianBlurEffectDescription(2.0f, GaussianBlurOptimization.Quality, GaussianBlurBorderMode.Hard));

            if (convolveButton.IsChecked == true)
            {
                var convolve = new ConvolveMatrixEffectDescription();
                convolve.SetKernelMatrix(new[] { -1.0f, -1.0f, -1.0f, -1.0f, 9.0f, -1.0f, -1.0f, -1.0f, -1.0f }, 3, 3);

                imageManipulator.AddEffectDescription(convolve);
            }

            if (colorButton.IsChecked == true)
            {
                // B&W
                imageManipulator.AddEffectDescription(new ColorMatrixEffectDescription(
                    new[] {
                            0.2125f, 0.2125f, 0.2125f, 0.0f,
                            0.7154f, 0.7154f, 0.7154f, 0.0f,
                            0.0721f, 0.0721f, 0.0721f, 0.0f,
                            0.0f, 0.0f, 0.0f, 1.0f,
                            0.0f, 0.0f, 0.0f, 0.0f
                    },
                    ColorMatrixAlphaMode.Straight, true));
            }

            if (sepiaButton.IsChecked == true)
            {
                // B&W
                imageManipulator.AddEffectDescription(new ColorMatrixEffectDescription(
                    new[] {
                            0.2125f, 0.2125f, 0.2125f, 0.0f,
                            0.7154f, 0.7154f, 0.7154f, 0.0f,
                            0.0721f, 0.0721f, 0.0721f, 0.0f,
                            0.0f, 0.0f, 0.0f, 1.0f,
                            0.0f, 0.0f, 0.0f, 0.0f
                    },
                    ColorMatrixAlphaMode.Straight, true)); 
                
                // Sepia
                imageManipulator.AddEffectDescription(new ColorMatrixEffectDescription(
                    new[] {
                            0.90f, 0.0f, 0.0f, 0.0f,
                            0.0f, 0.70f, 0.0f, 0.0f,
                            0.0f, 0.0f, 0.30f, 0.0f,
                            0.0f, 0.0f, 0.0f, 1.0f,
                            0.0f, 0.0f, 0.0f, 0.0f
                    },
                    ColorMatrixAlphaMode.Straight, true));
            }

            if (morphologyButton.IsChecked == true)
            {
                imageManipulator.AddEffectDescription(new MorphologyEffectDescription(MorphologyMode.Dilate, 1.0f, 0.0f));
            }

            if (saturationButton.IsChecked == true)
            {
                imageManipulator.AddEffectDescription(new SaturationEffectDescription());
            }

            if (hueButton.IsChecked == true)
            {
                imageManipulator.AddEffectDescription(new HueEffectDescription(180.0f));
            }

            if (brightnessButton.IsChecked == true)
            {
                imageManipulator.AddEffectDescription(new BrightnessEffectDescription(new Vector2(1.0f, 0.8f), new Vector2(0, 0.1f)));
            }

            if (polaroidButton.IsChecked == true)
            {
                imageManipulator.AddEffectDescription(new PolaroidEffectDescription());
            }
        }

        void CreateManipulator(IRandomAccessStream stream)
        {
            if (imageManipulator != null)
                imageManipulator.Dispose();

            imageManipulator = new ImageManipulator(stream);

            SynchronizeEffects();

            after.Source = imageManipulator.CreateSurfaceImageSource();
            imageManipulator.Manipulate(true);
        }

        private async void Page_Loaded_1(object sender, RoutedEventArgs e)
        {
            var file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync("default.jpg");

            using (var currentStream = await file.OpenReadAsync())
            {
                CreateManipulator(currentStream);
            }
        }

        private void before_PointerPressed_1(object sender, PointerRoutedEventArgs e)
        {
            Storyboard sb = new Storyboard();
            PointerDownThemeAnimation animation = new PointerDownThemeAnimation();
            Storyboard.SetTarget(animation, before);

            sb.Children.Add(animation);

            sb.Begin();
        }

        private void before_PointerReleased_1(object sender, PointerRoutedEventArgs e)
        {
            Storyboard sb = new Storyboard();
            PointerUpThemeAnimation animation = new PointerUpThemeAnimation();
            Storyboard.SetTarget(animation, before);

            sb.Children.Add(animation);

            sb.Begin();

            sb.Completed += async (o, evt) =>
                {
                    var picker = new Windows.Storage.Pickers.FileOpenPicker();
                    picker.FileTypeFilter.Add(".png");
                    picker.FileTypeFilter.Add(".jpg");
                    picker.FileTypeFilter.Add(".bmp");

                    var file = await picker.PickSingleFileAsync();

                    using (var stream = await file.OpenReadAsync())
                    {
                        if (stream == null)
                            return;

                        using (var currentStream = stream.CloneStream())
                        {
                            CreateManipulator(currentStream);
                        }

                        var source = new BitmapImage();
                        source.SetSource(stream);

                        before.Source = source;
                    }
                };
        }

        private void effect_Click(object sender, RoutedEventArgs e)
        {
            SynchronizeEffects();
            imageManipulator.Manipulate(true);
        }
    }
}
